﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;

namespace FasterWPF
{
    public class CPSBaseWindow : Window
    {
        #region Detect Window Size Imports
        [DllImport("user32.dll")]
        static extern IntPtr
        GetForegroundWindow();

        [DllImport("user32.dll", SetLastError = true)]
        static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);

        [StructLayout(LayoutKind.Sequential)]
        public struct RECT
        {
            public int Left;
            public int Top;
            public int Right;
            public int Bottom;
        }
        #endregion

        private RECT rect = new RECT();
        private Canvas _cnvs = null;
        private AdornerDecorator _ad = null;
        private string _cnvsguidAdorner = Guid.NewGuid().ToString();

        public Canvas Canvas
        {
            get { return _cnvs; }
            set { _cnvs = value; }
        }

        public AdornerDecorator AdornerDecorator
        {
            get { return _ad; }
            set { _ad = value; }
        }

        public string AdornerDecoratorGuid
        {
            get { return _cnvsguidAdorner; }
            set { _cnvsguidAdorner = value; }
        }

        public double WindowHeight 
        {            
            get{ return Math.Abs((rect.Top - rect.Bottom)); } 
        }

        public double WindowWidth 
        {            
            get{ return Math.Abs((rect.Left - rect.Right)); } 
        }

        protected RECT GetWindowRectangle()
        {            
            return rect;
        }

        public CPSBaseWindow()
        {
            this.WindowStartupLocation = WindowStartupLocation.CenterScreen;
            this.WindowState = WindowState.Minimized;
        }

        protected void AddMainParentToWindow(Action<AdornerDecorator> addAction)
        {
            addAction(_ad);
        }

        protected void StartInitializeComponent(Brush borderBrush, Thickness borderThickness)
        {
            _cnvs = new Canvas();
            _cnvs.Initialize(ContainerType.HorizontalPanel);
            _ad = new AdornerDecorator();

            this.Initialize(ContainerType.HorizontalPanel);
            this.BeginSettings<Window>()
                .SetItemBorderSettings(double.NaN, double.NaN, borderBrush, borderThickness)
                .EndSettings();

            this.BeginComposite<Window>()
                .AddExisting<Canvas, Window>(0, 0, _cnvs)
                .EndComposite<Window, WindowArgs>(null);

            _ad.Initialize(double.NaN, double.NaN, ContainerType.HorizontalPanel);
 
            _cnvs.BeginComposite<Canvas>(_cnvsguidAdorner)
                .AddExisting<AdornerDecorator, Canvas>(0, 0, _ad)
                .EndComposite<Canvas, CanvasArgs>(new CanvasArgs(0, 0, 1));
        }
        
        protected void EndInitializeComponent()
        {
            Application.Current.Properties["ResizeCorrectly"] = new Action<object, RoutedEventArgs>((o, ev) =>
            {
                GetWindowRect(GetForegroundWindow(), out rect);
                ResizeCorrectly(); });

            #region Window Re-Sized Hook

            Application.Current.MainWindow.AddHandler(Window.SizeChangedEvent, new RoutedEventHandler(
                (s, args) =>
                {
                    GetWindowRect(GetForegroundWindow(), out rect);
                    ResizeCorrectly();
                }));
            
            this.WindowState = WindowState.Maximized;
            GetWindowRect(GetForegroundWindow(), out rect);
            ResizeCorrectly();

            #endregion
        }

        protected override void OnContentRendered(EventArgs e)
        {
            base.OnContentRendered(e);
            GetWindowRect(GetForegroundWindow(), out rect);
            ResizeCorrectly();
        }

        protected virtual void ResizeCorrectly()
        {
        }
    }
}
